package com.itwk.gulimall.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itwk.common.utils.PageUtils;
import com.itwk.common.utils.Query;
import com.itwk.gulimall.product.dao.PmsCategoryDao;
import com.itwk.gulimall.product.entity.PmsCategoryEntity;
import com.itwk.gulimall.product.service.PmsCategoryBrandRelationService;
import com.itwk.gulimall.product.service.PmsCategoryService;
import com.itwk.gulimall.product.vo.webVo.Catalog2List;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("pmsCategoryService")
public class PmsCategoryServiceImpl extends ServiceImpl<PmsCategoryDao, PmsCategoryEntity> implements PmsCategoryService {
@Autowired
    private PmsCategoryBrandRelationService relationService; //用于关联修改 品牌关联表中的分类名
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PmsCategoryEntity> page = this.page(
                new Query<PmsCategoryEntity>().getPage(params),
                new QueryWrapper<PmsCategoryEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public List<PmsCategoryEntity> getCategoryTree() {

        List<PmsCategoryEntity> pmsCategoryEntities = baseMapper.selectList(null);

    /*    List<PmsCategoryEntity> categoryTree =new ArrayList<>();
        //嵌套循环实现
        for(PmsCategoryEntity category:pmsCategoryEntities){
            if(category.getParentCid()==0){
               category.setChildren( getChildrens1(category,pmsCategoryEntities));
                categoryTree.add(category);
            }

        }*/

        //流式遍历实现三级分类树形结构
        List<PmsCategoryEntity> categoryTree = pmsCategoryEntities.stream().filter(pmsCategoryEntity-> //取出流中单个对象按条件过滤
            pmsCategoryEntity.getParentCid()==0         //取出一级分类
        ).map(oneLevel -> {                  //map()方法中可以取出属性参数
            oneLevel.setChildren(getChildrens(oneLevel,pmsCategoryEntities));
            return oneLevel;             //递归思想进行子分类的处理
        }).sorted((level, level1) -> {
            return (level.getSort()!=null? level.getSort():0)-(level1.getSort()!=null? level1.getSort():0);
        }).collect(Collectors.toList());

        return categoryTree;


    }

    //对一级分类的子分类进行存储,流式编程
    public List<PmsCategoryEntity> getChildrens(PmsCategoryEntity category,List<PmsCategoryEntity> allCategory ){

        List<PmsCategoryEntity> childrens = allCategory.stream().filter(entity -> {

            return entity.getParentCid().equals(category.getCatId()) ; //取得当前分类的子分类
           // return entity.getParentCid() == category.getCatId();
        }).map(entity -> {
            entity.setChildren(getChildrens(entity, allCategory));
            return entity;                                    //将子分类存入上级分类，再次递归子分类的下级分类
        }).sorted((level,level1) -> {
            return (level.getSort()!=null? level.getSort():0)-(level1.getSort()!=null? level1.getSort():0);
        }).collect(Collectors.toList());

        return childrens;
    }


   /* //嵌套循环的递归方法
    public List<PmsCategoryEntity> getChildrens1(PmsCategoryEntity category,List<PmsCategoryEntity> allCategory ){
        List<PmsCategoryEntity> chiidrens =new ArrayList<>(); //用于存放子菜单

        for(PmsCategoryEntity level: allCategory){  //遍历所有的菜单
            if(level.getParentCid()==category.getCatId()){  //取得一个子菜单，递归下级菜单

                category.setChildren(getChildrens1(level,allCategory ));
                chiidrens.add(level);    //存入子菜单集合
            }

        }

        return chiidrens;

    }
    */
   //分类删除的重写
   @Override
   public void delCategoryByIds(List<Long> asList) {
       //Todo 判断是否该分类被引用

       baseMapper.deleteBatchIds(asList);

   }

    @Override
    public void updateRelation(PmsCategoryEntity pmsCategory) {
        baseMapper.updateById(pmsCategory);  //修改分类属性
        if(!StringUtils.isEmpty(pmsCategory.getName())){ //同步修改分类品牌中数据
            relationService.updateCategoryRelation(pmsCategory.getCatId(),pmsCategory.getName());

        }
    }

    @Override
    public List<PmsCategoryEntity> getLevel1() {
        //查询一级分类
        List<PmsCategoryEntity> categoryEntities = baseMapper.selectList(new QueryWrapper<PmsCategoryEntity>().eq("parent_cid", 0));

        return categoryEntities;
    }

    @Override  //使用redis进行缓存操作
    public Map<String,List<Catalog2List>> getCatalog2List() {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue(); //取得存储类型操作对象
        String catelog2List = ops.get("catelog2List");
        if(StringUtils.isEmpty(catelog2List)){   //redis查询为空，进行数据库查询
            Map<String, List<Catalog2List>> catalog2List = getCatalog2ListFromdb();
            String jsonString = JSON.toJSONString(catalog2List);// 序列化为Json
            ops.set("catelog2List", jsonString);   //存入redis
            return catalog2List; //返回查结果
        }
        //不为空反序列化 返回结果
        Map<String, List<Catalog2List>> result = JSON.parseObject(catelog2List, new TypeReference<Map<String, List<Catalog2List>>>() {
        });
           return result;
    }


    //抽取出方法，使用redis 缓存
    public Map<String,List<Catalog2List>> getCatalog2ListFromdb() {
      /* 拿到一级菜单，存为map,键为一级菜单id，值为二级菜单
        List<PmsCategoryEntity> level1 = getLevel1();
        */
      //查询出所有分类，根据分类的id ,遍历取出子id
        List<PmsCategoryEntity> categoryEntities = baseMapper.selectList(null);

                    List<PmsCategoryEntity> level1=getParent_cid(categoryEntities,0l);

                    Map<String, List<Catalog2List>> collect = level1.stream().collect(Collectors.toMap(l1 -> l1.getCatId().toString(), l1 -> {
                        List<PmsCategoryEntity> category2Entities = getParent_cid(categoryEntities,l1.getCatId());

                        //封装catalog2List 集合
                        if (category2Entities == null) {
                            return null;
                        }

            List<Catalog2List> catalog2 = category2Entities.stream().map(l2 -> {

                //找到当前二级下的三级数据，用于二级封装时使用
                List<PmsCategoryEntity> category3Entities = getParent_cid(categoryEntities,l2.getCatId());

                if (category3Entities == null) {
                    Catalog2List catalog2List = new Catalog2List(l2.getCatId().toString(), l2.getName(), l1.getCatId().toString(), null);
                    return catalog2List;
                }

                List<Catalog2List.Catalog3List> catalog3 = category3Entities.stream().map(l3 -> {
                    Catalog2List.Catalog3List catalog3List = new Catalog2List.Catalog3List(l3.getName(), l3.getCatId().toString(), l2.getCatId().toString());
                    return catalog3List;
                }).collect(Collectors.toList());
                Catalog2List catalog2List = new Catalog2List(l2.getCatId().toString(), l2.getName(), l1.getCatId().toString(), catalog3);
                return catalog2List;
            }).collect(Collectors.toList());

            return catalog2;
        }));


        return collect;
    }


       //修改业务代码，此处原来循环查库，并发吞吐量太低，抽取优化一次查库，循环获取
    private List<PmsCategoryEntity> getParent_cid(List<PmsCategoryEntity> list,Long catId) {
        List<PmsCategoryEntity> collect = list.stream().filter(item -> {
            return item.getParentCid().equals(catId);
        }).collect(Collectors.toList());
        return collect;

    }


}